RAII パターン
RAII = Resource Acquisition Is Initialization(資源の取得と同時に初期化する)
手動でのメモリ確保(new と malloc)と解放(delete と free)を対応させるため
しかし、C++11 で標準ライブラリで追加された、std::unique_ptr<T> が、メモリの 所有権 を持つ唯一の場所となり、一時的に使用するために ptr.get でメモリへのポインタを「借用」するようになった しかし、他のリソースに対しても有用 である
基本原則
上記の原則の結果、
値が存在すればリソースにアクセスでき、存在しなければリソースにアクセスできない
コンパイラ は変数のスコープが終了したらその値が破棄されることを保証するため、その値が持つリソースもスコープが終了した時点で解放されることが保証 される メリット
∵ 後から制御を変更する修正を行っても、値とリソースの生存期間は同じになる
e.g. mutex をロックしてアンロックするコード RAII パターンを使わない場合
code:c++
class ThreadSafeInt {
public:
ThreadSafeInt(int v) : value_(v) {}
void add(int delta) {
mu_.lock();
// ...
value_ += delta;
// ...
mu_.unlock();
}
}
この場合、以下のような mutex がロックされたままのコードを書くことができてしまう。
code:cpp
void add_with_modification(int delta) {
mu_.lock();
// ...
value_ += delta;
if (value_ > MAX_INT) {
return;
}
// ...
mu._unlock();
}
RAII パターンを使う場合
code:c++
class MutexLock {
public:
MutexLock(Mutex* m) : mu_(mu) { mu_->lock(); }
~MutexLock() { mu_->unlock(); }
private:
Mutex* mu_;
};
この場合だと、確実にアンロックすることができる
code:cpp
void add_with_modification(int delta) {
MutexLock with_lock(&mu_);
// ...
value_ += delta;
if (value_ > MAX_INT) {
return;
}
// ...
}